<script setup>

import {ref} from "vue";
import "codemirror/lib/codemirror.css";
import "codemirror/theme/material-darker.css"
import "codemirror/addon/lint/lint.css";
import "codemirror/addon/hint/show-hint.css";
import "codemirror/addon/fold/foldgutter.css";
import "codemirror/addon/lint/lint";
import "codemirror/addon/hint/show-hint";
import "codemirror/addon/fold/foldgutter";
import "codemirror/addon/edit/closebrackets";
import CodeMirror from "codemirror/lib/codemirror";

let props = defineProps({
  modelValue: {
    type: String,
    default: ""
  },
  mode: {
    type: String,
    default: "text/html"
  },
  readOnly: {
    type: Boolean,
    default: false
  }
})
let options = {
  mode: props.mode,
  theme: 'material-darker',
  lint: true,
  hint: true,
  lineNumbers: true,
  lineWrapping: true,
  autoCloseTags: true,
  autoCloseBrackets: true,
  showCursorWhenSelecting: true,
  foldGutter: true,
  gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
  tabSize: 4
};
let emit = defineEmits(['update:modelValue'])
let code = ref(null);
let editor;
let mode;
if (props.mode === "text/html") {
  Promise.all([
    import("codemirror/mode/htmlmixed/htmlmixed"),
    import("codemirror/addon/hint/html-hint"),
    import("codemirror/addon/hint/javascript-hint"),
    import("codemirror/addon/lint/javascript-lint"),
    import("codemirror/addon/hint/css-hint"),
    import("codemirror/addon/lint/css-lint"),
    import("codemirror/addon/edit/closetag")
  ]).then(() => {
    options.tabSize = 2;
    init();
  })
}

if (props.mode === "text/x-yaml") {
  Promise.all([import("codemirror/mode/yaml/yaml")]).then(() => {
    options.tabSize = 2;
    init();
  })
}

if (props.mode === "text/x-properties") {
  Promise.all([import("codemirror/mode/properties/properties")]).then(() => {
    init();
  })
}

if (props.mode === "application/json") {
  options.tabSize = 2;
  options.mode = {
    name: 'javascript',
    json: true
  }
  Promise.all([
    import("codemirror/mode/javascript/javascript"),
    import("codemirror/addon/hint/javascript-hint"),
  ]).then(() => {
    init();
  })
}

if (props.mode === "application/xml") {
  Promise.all([
    import("codemirror/mode/xml/xml"),
    import("codemirror/addon/edit/closetag")
  ]).then(() => {
    init();
  })
}

let init = () => {
  editor = CodeMirror.fromTextArea(code.value, options);
  editor.setValue(props.modelValue);
  editor.on("change", () => {
    emit("update:modelValue", editor.getValue());
  });
  editor.on("keypress", () => {
    editor.showHint();
  })

}
let setValue = (value) => {
  editor.setValue(value);
}

defineExpose({
  setValue
});
</script>

<template>
  <textarea ref="code"></textarea>
</template>
